import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;


/**
 * @author xhw
 */

@Slf4j
public class 异常 {

    public static void main(String[] args) {

        // 抛出一系列包含 Cause 的异常
        try {
            throwExceptionWithNestedCause();
        } catch (Exception e) {
            // 捕获到包含 Cause 的异常，并记录日志
            setLogger(e);
            // 如果含有 Cause，递归抛出 Cause
            if (e.getCause() != null) {
                // 递归抛出 Cause
                setLogger(e.getCause());
            }
        }
    }

    // 抛出一系列包含 Cause 的异常
    private static void throwExceptionWithNestedCause() {
        try {
            throwExceptionWithCause();
        } catch (Exception e) {
            // 抛出另一个包含 Cause 的异常
            throw new RuntimeException("中间异常", e);
        }
    }

    // 抛出一个包含 Cause 的异常
    private static void throwExceptionWithCause() {
        try {
            throwExceptionWithoutCause();
        } catch (Exception e) {
            // 故意造成一个数组越界异常，作为我们的 Cause
            int[] arr = new int[1];
            int num = arr[2]; // 访问索引为 2 的元素，但数组长度仅为 1
            throw new RuntimeException("数组越界", e);
        }
    }

    // 抛出一个不包含 Cause 的异常
    private static void throwExceptionWithoutCause() {
        // 将一个字符串转换为 Integer，但会抛出 NumberFormatException
        Integer.parseInt("尝试将 String 转为 Integer");
    }

    // 设置日志记录，记录异常信息
    private static void setLogger(Throwable e) {
        // 使用 SLF4J 记录异常消息和异常对象
        log.error("捕获到的异常: {}", e.getMessage(), e);

        // 记录线程名
        log.error("线程名: {}", Thread.currentThread().getName());

        // 记录异常调用栈
        log.error("异常调用栈: {}", Arrays.toString(e.getStackTrace()));

        // 如果异常包含 Cause，则递归调用 setLogger 记录 Cause 信息
        if (e.getCause() != null) {
            setLogger(e.getCause());
        }

        log.error("--------------------------------------");
    }
}
//如果异常一直被抛出，自己写代码
//1.main函数
//2.main函数里面多线程
//3.web程序的api
//兜底异常
//不处理的时候三个现象不一样，思考为什么


//回顾内存一直增长那个怎么